package com.cloudkinto.appletservice.orderoutput.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.appletservice.orderoutput.AppletOrderOutputService;
import com.cloudkinto.appletservice.orderoutput.vo.*;
import com.cloudkinto.common.DicBusinessConstant;
import com.cloudkinto.common.DicBusinessItemConstant;
import com.cloudkinto.common.constant.GlobalConstants;
import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.error.ErrorEnum;
import com.cloudkinto.common.exception.BizException;
import com.cloudkinto.common.exception.BizExceptionI18;
import com.cloudkinto.common.exception.NotSufficientFundsException;
import com.cloudkinto.common.utils.ExcelUtils;
import com.cloudkinto.common.utils.OrderCodeUtil;
import com.cloudkinto.common.utils.TimeUtils;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;
import com.cloudkinto.dao.*;
import com.cloudkinto.entity.*;
import com.cloudkinto.service.email.MailSenderService;
import com.cloudkinto.service.file.FileService;
import com.cloudkinto.service.finance.CompanyAccountService;
import com.cloudkinto.service.finance.vo.IdAndNameEntity;
import com.cloudkinto.service.operate.vo.OperateRes;
import com.cloudkinto.service.orderback.OrderBackService;
import com.cloudkinto.service.orderback.vo.OrderBackAddItem;
import com.cloudkinto.service.orderback.vo.OrderBackAddReq;
import com.cloudkinto.service.orderoutput.vo.*;
import com.cloudkinto.service.region.JpRegionService;
import com.cloudkinto.service.shipprice.ShipPriceService;
import com.cloudkinto.service.shop.ShopService;
import com.cloudkinto.service.storage.StorageService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * service实现类
 * </p>
 *
 * @author 张永远
 * @since 2020-06-04
 */
@Service
@Transactional(rollbackFor = Exception.class)//事务回滚
public class AppletOrderOutputServiceImpl extends ServiceImpl<OrderOutputDao, OrderOutputDo> implements AppletOrderOutputService {
    private static final String SHIPMENT_TYPE_0 = "普通";
    private static final String SHIPMENT_TYPE_1 = "次日达";
    private static final String ORDER_OUTPUT_TYPE_2 = "FBA转运";
    private static final String ORDER_OUTPUT_TYPE_1 = "一件代发";
    @Autowired
    private OrderOutputDao dao;
    @Autowired
    private ProductInfoDao productInfoDao;
    @Autowired
    private OrderOutputPackageDao packageDao;
    @Autowired
    private OrderOutputProductDao productDao;
    @Autowired
    private ShopDao shopDao;
    @Autowired
    private StorageService storageService;
    @Autowired
    private StorageDao storageDao;
    @Autowired
    private DicBusinessItemDao dicBusinessItemDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private ShopService shopService;
    @Autowired
    private OperateRecordDao operateRecordDao;
    @Autowired
    private FileService fileService;
    @Autowired
    private FbaStorageDao fbaStorageDao;



    @Override
    public AppletOrderOutputDetailRes detail(Long id) {
        OrderOutputDo entityDo = dao.selectById(id);
        AppletOrderOutputDetailRes res = new AppletOrderOutputDetailRes();
        if (entityDo == null) throw new BizExceptionI18("no.order.info");
        BeanUtils.copyProperties(entityDo, res);
//        res.setFileUrl(fileService.getFilePath(entityDo.getFileId()));
        return handlerDetailAfter(entityDo, res);
    }

    //查询明细之后要执行的业务定制处理
    private AppletOrderOutputDetailRes handlerDetailAfter(OrderOutputDo entityDo, AppletOrderOutputDetailRes res) {
        if (shopDao.selectById(entityDo.getShopId()) != null) {
            res.setShop(shopDao.selectById(entityDo.getShopId()).getShopName());
        }
        if (storageDao.selectById(entityDo.getStorageId()) != null) {
            res.setStorage(storageDao.selectById(entityDo.getStorageId()).getStorageName());
        }
        if (dicBusinessItemDao.selectById(entityDo.getTrackId()) != null) {
            res.setTrackName(dicBusinessItemDao.selectById(entityDo.getTrackId()).getDicItemValue());
        }
        FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(entityDo.getFbaStorageId());
        if(fbaStorageDo != null){
            res.setFbaStorage(fbaStorageDo.getFbaName());
        }
//        res.setReceiverName(entityDo.getReceiverName());
        if (entityDo.getDeliveryDate() != null)
            res.setDeliveryDate(TimeUtils.formatDate(entityDo.getDeliveryDate()));
        res.setOrderNumber(entityDo.getOrderOutputNumber());
//        res.setOrderTypeName(entityDo.getOrderType() != null && entityDo.getOrderType() == 2 ? ORDER_OUTPUT_TYPE_2 : ORDER_OUTPUT_TYPE_1);
        res.setShipmentTypeName(entityDo.getShipmentType() != null && entityDo.getShipmentType() == 1 ? SHIPMENT_TYPE_1 : SHIPMENT_TYPE_0);
        //查询对应包裹列表
//        QueryWrapper packageWrapper = new QueryWrapper();
//        packageWrapper.eq("order_output_id", res.getId());
//        //package
//        List<OrderOutputPackageDo> packageDoList = packageDao.selectList(packageWrapper);
//        List<OrderOutputPackageDetail> packageResList = new ArrayList<>();
//        for (OrderOutputPackageDo packageDo :
//                packageDoList) {
//            OrderOutputPackageDetail packageDetailRes = new OrderOutputPackageDetail();
//            BeanUtils.copyProperties(packageDo, packageDetailRes);
//            packageDetailRes.setSize(packageDo.getLength() + "+" + packageDo.getWidth() + "+" + packageDo.getHeight());
//            //product
//            List<OrderOutputProductDetail> productResList = new ArrayList<>();
//            QueryWrapper productWrapper = new QueryWrapper();
//            productWrapper.eq("package_id", packageDo.getId());
//            List<OrderOutputProductDo> productDoList = productDao.selectList(productWrapper);
//            for (OrderOutputProductDo productDetail :
//                    productDoList) {
//                OrderOutputProductDetail productDetailRes = new OrderOutputProductDetail();
//                BeanUtils.copyProperties(productDetail, productDetailRes);
//                ProductInfoDo productInfoDo = productInfoDao.selectById(productDetail.getProductId());
//                if (productInfoDo != null) {
//                    productDetailRes.setCommoditySku(productInfoDo.getCommoditySku());
//                    productDetailRes.setStorageSku(productInfoDo.getStorageSku());
//                    productDetailRes.setCommodityName(productInfoDo.getCommodityName());
//                }
//
//                productResList.add(productDetailRes);
//            }
//            packageDetailRes.setProductList(productResList);
//            packageResList.add(packageDetailRes);
//        }
//
//        res.setPackageList(packageResList);


//        //查询日志
//        List<OperateRes> operateResList = new ArrayList<>();
//        LambdaQueryWrapper<OperateRecordDo> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(OperateRecordDo::getThirdId, entityDo.getId()).eq(OperateRecordDo::getType, 3).orderByDesc(OperateRecordDo::getId);
//        List<OperateRecordDo> operateRecordDos = operateRecordDao.selectList(queryWrapper);
//        if (!CollectionUtils.isEmpty(operateRecordDos)) {
//            for (OperateRecordDo operateRecordDo : operateRecordDos) {
//                OperateRes operateRes = new OperateRes();
//                operateRes.setOperateTime(operateRecordDo.getOperateTime());
//                operateRes.setContent(operateRecordDo.getContent());
//                UserDo userDo = userDao.selectById(operateRecordDo.getOperateBy());
//                if (userDo != null) {
//                    operateRes.setOperateBy(userDo.getUserName() == null ? userDo.getUserAccount() :
//                            userDo.getUserName());
//                }
//                operateResList.add(operateRes);
//            }
//        }
//        res.setOperateResList(operateResList);
        return res;
    }

    @Override
    public SingleResult pageInit(Long companyId, Long userId) {
        Map map = new HashMap();
//        map.put("storageList", storageService.getList(new HashMap<>()));
//        List<Long> ids = new ArrayList<>();
//        LambdaQueryWrapper<DicBusinessItemDo> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(DicBusinessItemDo::getDicBusinessId, DicBusinessConstant.trackCompany);
//        List<DicBusinessItemDo> trackCompanyList = dicBusinessItemDao.selectList(wrapper);
//        List<IdAndNameEntity> trackList = new ArrayList<>();
//        for (DicBusinessItemDo itemDo :
//                trackCompanyList) {
//            trackList.add(new IdAndNameEntity(itemDo.getId().intValue(), itemDo.getDicItemValue()));
//        }
//        map.put("trackList", trackList);
//
//        List<Map> shopList = shopService.selectShopListInit(userId, companyId);
//        map.put("shopList", shopList);
        LambdaQueryWrapper<DicBusinessItemDo> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(DicBusinessItemDo::getDicBusinessId, DicBusinessConstant.outPutStatus);
        List<DicBusinessItemDo> dicBusinessItemDos = dicBusinessItemDao.selectList(wrapper1);

        map.put("status", dicBusinessItemDos);
        return SingleResult.success(map);
    }



    @Override
    public PageResult getListPage(Map<String, String> map) {
        QueryWrapper<OrderOutputDo> wrapper = queryBuild(map);
        IPage<OrderOutputDo> page = pageInit(map);
        page = this.page(page, wrapper);
        List<AppletOrderOutputListRes> resList = handlerListAfter(page.getRecords());
        PageResult result = new PageResult(resList, (int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), (int) page.getPages());
        return result;
    }



    //查询分页列表之后对列表数据的处理
    private List<AppletOrderOutputListRes> handlerListAfter(List<OrderOutputDo> list) {
        List<AppletOrderOutputListRes> result = new ArrayList<>();
        for (OrderOutputDo orderOutputDo :
                list) {
            AppletOrderOutputListRes listRes = new AppletOrderOutputListRes();
            BeanUtils.copyProperties(orderOutputDo, listRes);
            StorageDo storageDo = storageDao.selectById(orderOutputDo.getStorageId());
            if (storageDo != null) {
                listRes.setStorageName(storageDo.getStorageName());
            }
//            FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
//            if (fbaStorageDo != null) {
//                listRes.setFbaStorageName(fbaStorageDo.getFbaName());
//            }
            DicBusinessItemDo dic = dicBusinessItemDao.selectById(orderOutputDo.getTrackId());
            if (dic != null) {
                listRes.setTrackName(dic.getDicItemValue());
            }
            DicBusinessItemDo dicBusinessItemDo = dicBusinessItemDao.selectById(orderOutputDo.getStatus());
            if (dicBusinessItemDo != null) {
                listRes.setStatus(dicBusinessItemDo.getDicItemValue());
            }
//            if (1 == orderOutputDo.getShipmentType()) {
//                listRes.setShipmentTypeName(SHIPMENT_TYPE_1);
//            } else {
//                listRes.setShipmentTypeName(SHIPMENT_TYPE_0);
//            }
            listRes.setNumber(orderOutputDo.getOrderOutputNumber());
            listRes.setSendDate(TimeUtils.formatDate(orderOutputDo.getSendDate()));
//            listRes.setPoNumber(orderOutputDo.getPoNumber());
//            listRes.setVolume(getProductVolume(orderOutputDo));
            listRes.setReceiverName(orderOutputDo.getReceiverName());

            QueryWrapper wrapper = new QueryWrapper();
            wrapper.eq("order_output_id", orderOutputDo.getId());
            List<OrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper);
            if (packageDoList == null) continue;
            if (packageDoList.size() > 1) {

            } else if (packageDoList.size() == 1) {
                OrderOutputPackageDo packageDo = packageDoList.get(0);
                Double size = packageDo.getLength() + packageDo.getHeight()
                        + packageDo.getWidth();
                listRes.setShipPrice(new BigDecimal(size).setScale(0, RoundingMode.HALF_UP).doubleValue());
            }
            if (StringUtils.isBlank(listRes.getCommoditySku())) {
                QueryWrapper wrapper1 = new QueryWrapper();
                wrapper1.eq("order_id", orderOutputDo.getId());
                List<OrderOutputProductDo> productList = productDao.selectList(wrapper1);
                StringBuilder sb = new StringBuilder();
                for (OrderOutputProductDo productDo : productList) {
                    if (sb.length() > 0) {
                        sb.append(",");
                    }
                    sb.append(productInfoDao.selectById(productDo.getProductId()).getCommoditySku());
                }
                listRes.setCommoditySku(sb.toString());
            }
            result.add(listRes);
        }
        return result;
    }

    private double getProductVolume(OrderOutputDo orderOutputDo) {
        double volume = 0;
        LambdaQueryWrapper<OrderOutputProductDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderOutputProductDo::getOrderId, orderOutputDo.getId());
        List<OrderOutputProductDo> orderOutputProductDoList = productDao.selectList(wrapper);
        if (!CollectionUtils.isEmpty(orderOutputProductDoList)) {
            for (OrderOutputProductDo productDo : orderOutputProductDoList) {
                ProductInfoDo productInfoDo = productInfoDao.selectById(productDo.getProductId());
                if (productInfoDo != null) {
                    volume += (productInfoDo.getHeight() * productInfoDo.getWidth() * productInfoDo.getLength());
                }
            }
        }
        return volume / 1000000;

    }

    private IPage<OrderOutputDo> pageInit(Map<String, String> map) {
        IPage<OrderOutputDo> page = new Page();
        page.setSize(StringUtils.isNotBlank(map.get("pageSize")) ? Long.parseLong(map.get("pageSize")) : 10);
        page.setCurrent(StringUtils.isNotBlank(map.get("current")) ? Long.parseLong(map.get("current")) : 1);
        return page;
    }

    private QueryWrapper<OrderOutputDo> queryBuild(Map<String, String> map) {
        QueryWrapper<OrderOutputDo> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(map.get("keyword"))) {
            wrapper.or(orderOutputDoQueryWrapper -> orderOutputDoQueryWrapper.like("order_no", map.get("keyword").trim()).or(true)
                    .like("order_output_number", map.get("keyword").trim()).or(true)
                    .like("tel_phone", map.get("keyword").trim()).or(true)
                    .like("track_number", map.get("keyword").trim()).or(true)
                    .like("commodity_sku", map.get("keyword").trim()).or(true)
                    .like("storage_sku", map.get("keyword").trim()).or(true)
                    .like("receiver_name", map.get("keyword").trim()));
        }
        if (StringUtils.isNotBlank(map.get("status"))) {
            wrapper.eq("status", map.get("status"));
        }
        if (StringUtils.isNotBlank(map.get("startDate"))) {
            wrapper.ge("send_date", map.get("startDate"));
        }
        if (StringUtils.isNotBlank(map.get("endDate"))) {
            wrapper.le("send_date", map.get("endDate"));
        }
        if (StringUtils.isNotBlank(map.get("storageId"))) {
            wrapper.eq("storage_id", map.get("storageId"));
        }
        if (StringUtils.isNotBlank(map.get("trackId"))) {
            wrapper.eq("track_id", map.get("trackId"));
        }
        if (StringUtils.isNotBlank(map.get("shopId"))) {
            wrapper.eq("shop_id", map.get("shopId"));
        }
        wrapper.eq("company_id", map.get("companyId"));

        wrapper.orderByDesc("id");
        return wrapper;
    }



}
